/*
闭包：能够捕获所在环境的匿名函数（跟C# 里的 委托差不多意思）

*/

//基本语法
pub fn test() {
    let closer = |x: i32| x + 1;
    let closer1 = |x: i32| x + 1;
    fn add_one_v1(x: u32) -> u32 {
        x + 1
    }
    let add_one_v2 = |x: u32| -> u32 { x + 1 };
    let add_one_v3 = |x: u32| x + 1;
    let add_one_v4 = |x: u32| x + 1;
    println!("{0}", closer(5));
    println!("{0}", closer1(5));

    let t1 = 5;
    let ct1 = move || t1 + 1;
    println!("{0}", t1);
    println!("{0}", ct1());
    println!("{0}", t1);

    let vec = vec![1, 2, 3];
    let consumes_vec = move || {
        println!("Vec: {:?}", vec); // vec 的所有权被移动
                                    // drop(vec) 隐式调用
    };

    consumes_vec();
    consumes_vec();
}

/*
当闭包从环境中捕获一个值时，会分配内存去存储这些值。对于有些场景来说，这种额外的内存分配会成为一种负担。与之相比，函数就不会去捕获这些环境值，因此定义和使用函数不会拥有这种内存负担。
 */

//闭包还有三种内置 特征 写法
/*
1.fnOnce 获取所有权，该类型的闭包会拿走被捕获变量的所有权。Once 顾名思义，说明该闭包只能运行一次：
2.fnMut 可变借用
3.fn 不可变借用

*/

/*

   pub fn fn_once<F>(func:F) where F:FnOnce(usize)->bool
    {
        println!("{}",func(5));
        //println!("{}",func(2));
    }

*/

pub fn fn_once<F>(func: F)
where
    F: FnOnce(usize) -> bool + Copy,
{
    println!("{}", func(3));
    println!("{}", func(4));
}

pub fn fn_once_test() {
    let v = vec![1, 2, 3, 4, 5];
    fn_once(|x| x == v.len());
    fn_once(|z| z == v.len())
}

pub fn fn_mut<F>(mut fnMut: F)
where
    F: FnMut(u32) -> u32,
{
    let mut x:u32=66;
    println!("fn_mut{}",fnMut(x));

}
pub fn fn_mut_test()
{
  let mut x=666;

  println!("fn_mut_test{}",x);
  fn_mut(|x| x+777);
  println!("fn_mut_test_fn_mut{}",x);

}